<?php

/**
 * Store
 *
 * Модель для модуля магазина
 *
 * @package Store
 * @author Игорь Будасов aka Lord <igor.budasov@gmail.com>
 */

class Store extends Zend_Db_Table_Abstract
{

/*------------------------------------------------------------------------------*/

	// имя таблицы, с которой будет работать Zend_Db_Table
	protected $_name = 'store_categories';

/*------------------------------------------------------------------------------*/
/* Методы для акций */
/*------------------------------------------------------------------------------*/

	/**
	* Метод для извлекания текущих акций
	*/

	public function getCurrentActions()
	{
		$currentDate = date('Y-m-d');
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_actions')
					->where('date_from <= "' . $currentDate.'"')
					->where('"'.$currentDate . '" <= date_to')
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Обновление категории товаров магазина
	*
	* @param array $data
	* @param int $id
	* @return int
	*/

	public function updateAction($data = array(), $id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_actions');
		// обновляем
		return $this->update($data, 'id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для извлекания всех акций
	*/

	public function getAllActions()
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_actions')
					->order('date_to DESC')
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения одной акции
	*
	* @param int $id
	*/

	public function getAction($id = 0)
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_actions')
					->where('id = '.$id)
					;

		// возвращаем результат
		return  $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления акции по айдишнику
	*
	* @param int $id
	* @return int
	*/

	public function delAction($id)
	{
		$this->_setTable('store_actions');
		return $this->delete('id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Добавление акции
	*
	* @param array $data
	* @return int
	*/

	public function addAction($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_actions');

		// отправляем данные на добавление и возвращаемся
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/
/* Методы для фильтра товаров */
/*------------------------------------------------------------------------------*/

	/**
	* Добавление записи о параметрах фильтра
	*
	* @param array $data
	* @return int
	*/

	public function saveFilterParams($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_filter');
		// добавляем
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получает свойства товаров в категории по массиву айдишников категорий
	* Свойства для фильтра товаров
	*
	* @param array $children
	* @return Zend_Db_Table_Rowset_Abstract
	*/
	public function getCategoryProperties($children)
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_properties_categories_cross')
					->join('store_properties', 'store_properties.id = store_properties_categories_cross.property_id')
					;
		foreach($children as $cid)
		{
			$query->orwhere('store_properties_categories_cross.category_id = ' . $cid);
			$query->where('store_properties.show_in_filter = 1');
			$query->where('store_properties.active = 1');
		}


		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	public function getPropertyValues($pid)
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_properties_goods_cross')
					->where('property_id = '.$pid)
					->group('value')
					;
		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получение значений фильтра из базы по айдишнику из куки
	*
	* @param int $id
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getFilter($id)
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_filter')
					->where('id = ' . $id)
					;

		// возвращаем результат
		return  $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/
/* Методы для контроллера Комментариев к товару */
/*------------------------------------------------------------------------------*/

	/**
	* Добавление комментария к товару магазина
	*
	* @param array $data
	* @return int
	*/

	public function addComment($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_comments');

		// отправляем данные на добавление и возвращаемся
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления комментария к товару
	*
	* @param int $id
	* @return int
	*/

	public function delComment($id)
	{
		$this->_setTable('store_comments');

		return $this->delete('id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Одобрение комментария к товару
	*
	* @param int $id
	* @return int
	*/

	public function approveComment($id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_comments');
		$data['approved'] = 1;
		// обновляем
		return $this->update($data, 'id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Функиця для получения одобреных комментариев к товару
	*/

	public function getApprovedComments($id)
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_comments')
					->where('approved = 1 ')
					->where('gid = ' . $id)
					->order('type')
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Функиця для получения одобреных комментариев
	*/

	public function getAllApprovedComments()
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from(array('store_comments'=>'store_comments'),
						   array('user_name'=>'name', 'id', 'comment'))
					->where('store_comments.approved = 1')
					->join('store_goods', 'store_comments.gid = store_goods.id')
					->order('type')
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Функиця для получения не одобреных комментариев
	*/

	public function getNotApprovedComments()
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from(array('store_comments'=>'store_comments'),
						   array('user_name'=>'name', 'comment_id'=>'id', 'comment'))
					->where('store_comments.approved = 0')
					->join('store_goods', 'store_comments.gid = store_goods.id')
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Функиця для получения одного комментария
	*/

	public function getComment($id)
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_comments')
					->where('id = ' . $id)
					;

		// возвращаем результат
		return  $this->fetchRow($query);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Добавление категории товаров в магазин
	*
	* @param array $data
	* @return int
	*/

	public function addDump($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('backup');

		// отправляем данные на добавление и возвращаемся
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/
/* Методы для контроллера Валют */
/*------------------------------------------------------------------------------*/

	/**
	* Метод возвращает все доступные валюты
	*/

	public function getAllValutes()
	{
		$query = $this->select()
			->from('store_valutes')
			->order('main desc')
			->setIntegrityCheck(false)
			;
		return $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления валюты
	*
	* @param int $id
	* @return int
	*/

	public function delValute($id)
	{
		$this->_setTable('store_valutes');

		return $this->delete('id = ' . $id);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Обновление валюты
	*
	* @param array $data
	* @param int $id
	* @return int
	*/

	public function updateValute($data = array(), $id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_valutes');
		// обновляем
		return $this->update($data, 'id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод возвращает указанную валюту
	*/

	public function getValute($id = 0)
	{
		$query = $this->select()
			->from('store_valutes')
			->where('id = ?', $id)
			->limit(1)
			->setIntegrityCheck(false)
			;
		return $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Добавление валюты
	*
	* @param array $data
	* @return int
	*/

	public function addValute($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_valutes');
		// добавляем
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Обнуляем основную валюту,
	* чтоб потом выставить активную
	*
	* @param array $data
	* @return int
	*/

	public function unsetMainValute()
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_valutes');
		$data['main'] = 0;
		// обновляем
		return $this->update($data, '');
	}

/*------------------------------------------------------------------------------*/
/* Методы для контроллера Производителей товаров */
/*------------------------------------------------------------------------------*/

	/**
	* Обновление данных о производителе товаров
	*
	* @param array $data
	* @param int $id
	* @return int
	*/

	public function updateManufacturer($data = array(), $id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_manufacturers');
		// обновляем
		return $this->update($data, 'id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Добавление производителя
	*
	* @param array $data
	* @return int
	*/

	public function addManufacturer($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_manufacturers');
		// добавляем
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления производителя по айдишнику
	*
	* @param int $id
	* @return int
	*/

	public function delManufacturer($id)
	{
		$this->_setTable('store_manufacturers');

		return $this->delete('id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем производителя по айдишнику
	*
	* @param int $id
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getManufacturer($id = 0)
	{
		$query = $this->select()
			->from('store_manufacturers')
			->setIntegrityCheck(false)
			->where('id = ?', $id)
			// поставим лимит, чтоб запрос не
			// потрошил базу дальше найденой записи
			->limit(1)
			;
		return $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получить список всех производителей
	*/

	public function getAllManufacturers()
	{
		$query = $this->select()
			->from('store_manufacturers')
			->setIntegrityCheck(false)
			->order('name asc')
		;

		return $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получить производителей с указаными айдишниками
	* Аргументом принимает массив, ключем которого есть айдишник производителя
	*/

	public function getManufacturers( $data = array() )
	{
		$query = $this->select()
			->from('store_manufacturers')
			->setIntegrityCheck(false)
			->order('name asc')
		;
		foreach($data as $k=>$v)
		{
			$query = $query->orwhere('id = ?', $k);
		}

		return $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/
/* Методы для контроллера Картинок товаров */
/*------------------------------------------------------------------------------*/

	/**
	* Обновление данных об изображении
	*
	* @param array $data
	* @param int $id
	* @return int
	*/

	public function updateImage($data = array(), $id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_images');
		// обновляем
		return $this->update($data, 'id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Очистка предыдущих главных картинок для одного товара
	*
	* @param array $data
	* @param int $id - айдишник товара
	* @return int
	*/

	public function clearMainImage($id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_images');
		return $this->update(array('main'=>'0'), 'gid = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Добавление фотографии товара
	*
	* @param array $data
	* @return int
	*/

	public function addImage($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_images');
		// добавляем
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения картинки по айдишнику
	*
	* @param mixed $id
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getImage($id = 0)
	{
		$query = $this->select()
			->from('store_images')
			->setIntegrityCheck(false)
			->where('id = ?', $id)
			// поставим лимит, чтоб запрос не
			// потрошил базу дальше найденой записи
			->limit(1)
			;
		return $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления картинки по айдишнику
	*
	* @param int $id
	* @return int
	*/

	public function delImage($id)
	{
		$this->_setTable('store_images');

		return $this->delete('id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем главную картинку к товару
	*
	* @param int $id
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getMainImage($id = 0)
	{
		$query = $this->select()
			->from('store_images')
			->setIntegrityCheck(false)
			->where('gid = ?', $id)
			->order('main Desc')
			->limit(1)
			// поставим лимит, чтоб запрос не
			// потрошил базу дальше найденой записи
			->limit(1)
			;
		return $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем все картинки товара по айдишнику товара
	*
	* @param int $id
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getGoodImages($id = 0)
	{
		$query = $this->select()
			->from('store_images')
			->setIntegrityCheck(false)
			->where('gid = ?', $id)
			->order('main DESC')
			;
		return $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получить картинки по указаным айдишникам
	* Аргументом принимает объект товаров Zend_Db_Table
	*/

	public function getImages( $data = array() )
	{
		$this->_setupTableName('store_images');
		$query = $this->select()
			->from('store_images')
			->setIntegrityCheck(false)
			->order('main desc')
		;
		foreach($data as $k=>$v)
		{
			$query = $query->orwhere('gid = ' . $v['id']);
		}

		return $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/
/* Методы для контроллера Товаров */
/*------------------------------------------------------------------------------*/

	/**
	* Обновление данных о товаре
	*
	* @param array $data
	* @param int $id
	* @return int
	*/

	public function updateGood($data = array(), $id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_goods');
		// обновляем
		return $this->update($data, 'id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Добавление товара
	*
	* @param array $data
	* @return int
	*/

	public function addGood($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_goods');
		// добавляем
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления товара по айдишнику
	*
	* @param int $id
	* @return int
	*/

	public function delGood($id)
	{
		$this->_setTable('store_goods');

		return $this->delete('id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения товара по айдишнику
	*
	* @param int $id
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getGood($id = 0)
	{
		$query = $this->select()
			->from('store_goods')
			->setIntegrityCheck(false)
			->where('id = ?', $id)
			->limit(1)
			;
		return $this->fetchRow($query);

	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения товара по его URL
	*
	* @param string $url
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getGoodByUrl($url = '')
	{
		$query = $this->select()
			->from('store_goods')
			->setIntegrityCheck(false)
			->where('url = ?', $url)
			->limit(1)
			;
		return $this->fetchRow($query);

	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения значения кастомного свойства товара
	*
	* @param int $gid - айдишник товара
	* @param int $pid - айдишник свойства
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getGoodPropertyValue($gid = 0, $pid = 0)
	{
		$query = $this->select()
			->from('store_properties_goods_cross')
			->setIntegrityCheck(false)
			->where('good_id = ?', $gid)
			->where('property_id = ?', $pid)
			->limit(1)
			;
		return $this->fetchRow($query);

	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения свойств товара по айдишнику
	*
	* @param int $id - айдишник самого товара
	* @param int $cid - айдишник категории товара
	* @param string $type - где будут показываться свойстваб good|compare
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getGoodProperties($id = 0, $cid = 0, $type = '')
	{
		$query = $this->select()
					// отключаем проверку
					->setIntegrityCheck(false)
					// из кросс-таблицы не достаем ничего
					->from('store_properties_categories_cross', array())
					// присоединяем таблицу свойств
					->joinInner('store_properties',
								// указываем связку
								"store_properties_categories_cross.property_id = store_properties.id",
								// из нее достаем указаные поля
								array('id', 'name', 'active', 'show_in_good',
									  'show_in_compare', 'show_in_filter')
								)
					// условие извлечения из кросс-таблицы
					->where('store_properties_categories_cross.category_id = ' . $cid)
					->where('store_properties.active = 1')
					;
		if(!empty($type))$query->where('store_properties.show_in_'.$type.' = 1');
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения товара по его имени
	*
	* @param string $name
	* @return Zend_Db_Table_Row_Abstract|null
	*/

	public function getGoodByName($name = '')
	{
		$query = $this->select()
			->from('store_goods')
			->setIntegrityCheck(false)
			->where('name LIKE "%'.$name.'%"' )
			->limit(1)
			;
		return $this->fetchRow($query);

	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения списка товаров,
	* который будет отображаться на фронте
	*
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getFront()
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_goods')
					->order('hit desc')
					->order('rating desc')
					->where('front = 1')
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения всех товаров
	*
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getAllGoods()
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_goods')
					->order('cid')
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Функиця для получения новых товаров на фронте
	* Установлен лимит
	*/

	public function getNewGoods()
	{
		// ORDER BY RAND() LIMIT
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_goods')
					->order('id desc')
					->limit(8)
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Функиця для получения хитовых товаров для фронта
	* Установлен лимит
	*/

	public function getHitGoods()
	{
		// ORDER BY RAND() LIMIT
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_goods')
					->order('hit desc')
					->limit(8)
					;

		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Функиця для получения товаров по массиву с айдишниками
	*/

	public function getSomeGoods($goods = array())
	{
		// основа запроса
		$query = $this->select()
					->setIntegrityCheck(false)
					->from('store_goods')
					;
		if(!empty($goods))
		{
			foreach($goods as $good)
			{
				$query->orwhere(' id = ' . $good );
			}
		}
		else
		{
			return false;
		}
		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения списка товаров из категории или производителя
	* Если $mid = 0 -- то достает из категории,
	* если $cid = 0 -- то достает из производителя
	*
	* @param array $children
	* @param int $cid
	* @param int $mid
	* @param string/int $sort
	* @param array $pager
	*
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getGoods($children = array(),
							 $cid = 0,
							 $mid = 0,
							 $sort = 0,
							 $pager = array())
	{
		/*
		$front = Zend_Registry::get('front');
		// настройка пэйджера, чтоб он выбирал нужное количество записей
		$pager['page'] = ($front->getParam('page'))
					   ? $front->getParam('page')
					   : 0;
		$pager['itemsPerPage'] = 2;//$front->_helper->config()->common->itemCountPerPage;
		*/
		// основа запроса
		$query = $this->select()
					->from('store_goods')
					->setIntegrityCheck(false)
					//->limitPage($pager['page'], $pager['itemsPerPage'])
					;
		// если выбрана категория - выбираем товары также и из ее детей
		if(!empty($children) and $cid != 0 )
		{
			// сортировка
			if(    $sort == 'pricedesc')$query->order('price desc');

			elseif($sort == 'priceasc') $query->order('price asc');

			elseif($sort == 'ratedesc') $query->order('rating desc')
											  ->order('hit desc');

			elseif($sort == 'rateasc')  $query->order('rating asc')
											  ->order('hit desc');

			elseif($sort == 'stock')    $query->order('stock desc')
											  ->order('hit desc')
											  ->order('rating desc');

			elseif($sort == 'hit')      $query->order('hit desc')
											  ->order('rating desc');

			elseif (empty($sort) or $sort == 0)
										$query->order('hit desc')
											  ->order('rating desc');


			foreach($children as $k => $v)
			{
				if($mid != 0)
				{
					$query->orwhere("mid = " . $mid . " and cid = " . $v);
				}
				else
				{
					$query->orwhere(' cid = ' . $v );
				}
			}


		}



		// возвращаем результат
		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для получения списка товаров на основе фильтра
	*
	* @param array $children -- дочерние категории
	* @param array $filter -- данные для фильтрации
	* @param string/int $sort -- сортировка после того, как отфильтровано
	*
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getFilteredGoods($children   = array(),
									 $filter     = array(),
									 $sort       = '',
									 $logic      = 1)
	{
		// основа запроса
		$query = $this->select()
					// выбираем из таблицы товаров
					->from('store_goods',
					// все поля и ложный столбец с количеством совпадений
						   array('*',   'COUNT(store_goods.id) as props_set'))
					// присоединяем таблицу со свойствами и значениями
					->join('store_properties_goods_cross',
					// условие присоединения
						   'store_goods.id = store_properties_goods_cross.good_id',
					// поля для выборки, без айдишника, чтоб не перетереть айди товара
						   array('property_id', 'value'))
					// отключаем проверку совместимости
					->setIntegrityCheck(false);

		// если выбрана категория - выбираем товары также и из ее детей
		if(!empty($children) and isset($filter['cid']) and $filter['cid'] != 0 )
		{
			// сортировка
			if(    $sort == 'pricedesc')$query->order('price desc');

			elseif($sort == 'priceasc') $query->order('price asc');

			elseif($sort == 'ratedesc') $query->order('rating desc')
											  ->order('hit desc');

			elseif($sort == 'rateasc')  $query->order('rating asc')
											  ->order('hit desc');

			elseif($sort == 'stock')    $query->order('stock desc')
											  ->order('hit desc')
											  ->order('rating desc');

			elseif($sort == 'hit')      $query->order('hit desc')
											  ->order('rating desc');

			elseif (empty($sort) or $sort == 0)
										$query->order('hit desc')
											  ->order('rating desc');
			// условия

			$price  = ($filter['price_from'] and $filter['price_to'])
					? ' "'.$filter['price_from'].'" <= price AND price <= "'.$filter['price_to'].'" '
					: '';
			$rating = ($filter['rating_from'] and $filter['rating_to'])
					? ' '.$filter['rating_from'].' <= rating AND rating <= '.$filter['rating_to'].' '
					: '';
			$stock = ($filter['stock'] == 1 or $filter['stock'] == 0)
				   ? ' stock = '.$filter['stock'].' '
				   : '';
			$hit   = ($filter['hit'] == 1 or $filter['hit'] == 0)
				   ? ' hit = '.$filter['hit'].' '
				   : '';
			foreach($children as $k => $v)
			{
				if($filter['manufacturers'] !== null)
				{
					foreach($filter['manufacturers'] as $man)
					{
						if($filter['properties'] !== null)
						{
							$countProperties = count($filter['properties']);
							foreach($filter['properties'] as $propertyId=>$property)
							{
								foreach($property as $value)
								{
									$query->orwhere(' store_properties_goods_cross.value LIKE "%'.$value.'%" AND store_properties_goods_cross.property_id = '.$propertyId.' ');
								}
							}
						}
						$query->orwhere(' cid='.$v.' and mid = '.$man.' ');
						if(!empty($price))$query->where($price);
						if(!empty($rating))$query->where($rating);
						if(!empty($stock))$query->where($stock);
						if(!empty($hit))$query->where($hit);

					}
				}
				else
				{
					if($filter['properties'] !== null)
					{
						$countProperties = count($filter['properties']);
						foreach($filter['properties'] as $propertyId=>$property)
						{
							foreach($property as $value)
							{
								$query->orwhere(' store_properties_goods_cross.value LIKE "%'.$value.'%" AND store_properties_goods_cross.property_id = '.$propertyId.' ');
							}
						}
					}
					if(!empty($price)) $query->where($price);
					if(!empty($rating))$query->where($rating);
					if(!empty($stock)) $query->where($stock);
					if(!empty($hit))   $query->where($hit);
					//$query->where('ok > ' . count($filter['properties']));
				}
			}
		}

		$query->group('store_goods.id');
		$countProperties = (isset($countProperties))
						 ? $countProperties
						 : 0;
		// жесткая И-логика
		if($logic == 1)$query->having('props_set >= '.$countProperties);
		// смешанная логика
		if($logic == 2)$query->having('props_set > '.intval($countProperties/2));
		// для ИЛИ-логики просто проигнорируем having

		return  $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/
/* Методы для контроллера Свойств товаров */
/*------------------------------------------------------------------------------*/

	/**
	* Получаем свойство по айдишнику
	*
	* @param int $id
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getProperty($id = 0)
	{
		$query = $this->select()
			->from('store_properties')
			->where('id = ?', $id)
			->setIntegrityCheck(false)
			// поставим лимит, чтоб запрос не
			// потрошил базу дальше найденой записи
			->limit(1)
			;
		return $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем айдишники категории по айдишнику свойства
	*
	* @param int $id
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getPropertyCategoriesCross($id = 0)
	{
		$query = $this->select()
			->setIntegrityCheck(false)
			->from('store_properties_categories_cross')
			->where('property_id = ?', $id)
			;
		return $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления зависимости свойства от категории
	* по айдишнику свойства
	*
	* @param int $id
	* @return int
	*/

	public function delPropertyCategoryCross($id)
	{
		$this->_setTable('store_properties_categories_cross');

		return $this->delete('property_id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления  свойства товара
	* по айдишнику свойства
	*
	* @param int $id
	* @return int
	*/

	public function delProperty($id)
	{
		$this->_setTable('store_properties');

		return $this->delete('id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления зависимости свойства от товара
	* по айдишнику свойства
	*
	* @param int $id
	* @return int
	*/

	public function delPropertyGoodCross($id)
	{
		$this->_setTable('store_properties_goods_cross');

		return $this->delete('good_id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем все свойства
	*
	* @param int $id
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getProperties()
	{
		$query = $this->select()->setIntegrityCheck(false)->from('store_properties');
		return $this->fetchAll($query);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Добавление свойства товаров в магазин
	*
	* @param array $data
	* @return int
	*/

	public function addProperty($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_properties');

		// отправляем данные на добавление и возвращаемся
		return $this->insert($data);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Добавление связи свойства товаров и категорий
	*
	* @param array $data
	* @return int
	*/

	public function addPropertyCategoryCross($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_properties_categories_cross');

		// отправляем данные на добавление и возвращаемся
		return $this->insert($data);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Добавление связи свойства товара, свойства и его значения
	*
	* @param array $data
	* @return int
	*/

	public function addGoodPropertyValue($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_properties_goods_cross');

		// отправляем данные на добавление и возвращаемся
		return $this->insert($data);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Обновление свойство товаров
	*
	* @param array $data
	* @param int $id
	* @return int
	*/

	public function updateProperty($data = array(), $id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_properties');
		// обновляем
		return $this->update($data, 'id = ' . $id);
	}

/*------------------------------------------------------------------------------*/
/* Методы для контроллера Категорий товаров */
/*------------------------------------------------------------------------------*/

	/**
	* Метод для удаления категории по айдишнику
	*
	* @param int $id
	* @return int
	*/

	public function delCategory($id)
	{
		$this->_setTable('store_categories');

		return $this->delete('id = ' . $id);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем все дочерние категории для
	* категории с указаным айдишником
	*
	* @param int $id
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getChildren($pid = 0)
	{
		$query = $this->select()
			->from('store_categories')
			->order('order desc')
			->where('pid = ?', $pid)
			;
		return $this->fetchAll($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем все родительские категории для
	* категории с указаным айдишником
	*
	* @param int $id
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getParent($id = 0)
	{
		$query = $this->select()
			->from('store_categories')
			->where('id = ?', $id)
			;
		return $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем категорию по айдишнику
	*
	* @param int $id
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getCategory($id = 0)
	{
		$query = $this->select()
			->from('store_categories')
			->where('id = ?', $id)
			// поставим лимит, чтоб запрос не
			// потрошил базу дальше найденой записи
			->limit(1)
			;
		return $this->fetchRow($query);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получаем категорию по URL
	*
	* @param string $url
	* @return Zend_Db_Table_Rowset_Abstract
	*/

	public function getCategoryByUrl($url = '')
	{
		$query = $this->select()
			->from('store_categories')
			->where('url = ?', $url)
			// поставим лимит, чтоб запрос не
			// потрошил базу дальше найденой записи
			->limit(1)
			;
		return $this->fetchRow($query);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Добавление категории товаров в магазин
	*
	* @param array $data
	* @return int
	*/

	public function addCategory($data = array())
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_categories');

		// отправляем данные на добавление и возвращаемся
		return $this->insert($data);
	}

/*------------------------------------------------------------------------------*/

	/**
	* Получить список всех категорий товаров
	*/

	public function getAllCategories()
	{
		$query = $this->select()
			->from('store_categories')
			->setIntegrityCheck(false)
			->order('order desc')

		;

		return $this->fetchAll($query);
	}

/*-----------------------------------------------------------------------------*/

	/**
	* Обновление категории товаров магазина
	*
	* @param array $data
	* @param int $id
	* @return int
	*/

	public function updateCategory($data = array(), $id = 0)
	{
		// установим имя таблицы на всякий случай
		$this->_setTable('store_categories');
		// обновляем
		return $this->update($data, 'id = ' . $id);
	}

/*==============================================================================*/

	/**
	* Приватный метод для смены имени таблицы
	*
	* @param string $table
	*/

	private function _setTable($table = '')
	{
		$this->_name = $table;
		return;
	}

/*------------------------------------------------------------------------------*/

}
